package com.sykj.why.mongo.service.impl;

import com.sykj.why.exception.WhyException;
import com.sykj.why.mongo.dao.MenuTDao;
import com.sykj.why.mongo.document.entity.MenuCategoryT;
import com.sykj.why.mongo.document.entity.MenuT;
import com.sykj.why.mongo.dto.PageDTO;
import com.sykj.why.mongo.enums.exception.ResultEnum;
import com.sykj.why.mongo.service.MenuCategoryTService;
import com.sykj.why.mongo.service.MenuTService;
import com.sykj.why.mongo.vo.entity.MenuTVo;
import com.sykj.why.util.BaseTools;
import com.sykj.why.util.DateTool;
import com.sykj.why.util.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service("MenuTService")
public class MenuTServiceImpl extends BasicServiceImpl<MenuT> implements MenuTService {

    @Autowired
    private MenuTDao menuTDao;

    @Autowired
    private MenuCategoryTService menuCategoryTService;

    /**
     * 添加菜单
     * @param menuT
     */
    @Override
    public void saveMenu(MenuT menuT) {
        //验证菜单名称是否重复
        verifyName(menuT);
        //排序
        long count = menuTDao.count(MenuT.class, false);
        menuT.setSort((int) count);
        //不能超过三级
        if (menuT.getLevel() == 4){
            throw new WhyException(ResultEnum.MENU_LEVEL_NOT_THREE);
        }
        //设置时间
        menuT.setCreateTime(DateTool.getSystemTime());
        menuT.setUpdateTime(DateTool.getSystemTime());
        //保存
        menuTDao.save(menuT);
    }

    /**
     * 删除菜单
     * @param id
     */
    @Override
    public void removeMenu(String id) {
        //通过Id查询菜单
        MenuT menuT = findById(id);
        //逻辑删除菜单
        menuTDao.remove(menuT);
        //删除子菜单及该菜单下的菜单分类
        removeChildren(id);
        List<MenuCategoryT> list = menuCategoryTService.findMenuCategoryListByMenuId(id);
        if (list.size()>0){
            for (MenuCategoryT menuCategoryT : list){
                menuCategoryTService.removeMenuCategory(menuCategoryT.getId());
            }
        }

    }

    /**
     * 删除子级菜单
     * @param pid
     */
    private void removeChildren(String pid){
        Query query = new Query();
        query.addCriteria(Criteria.where("removed").is(false).and("pid").is(pid));
        List<MenuT> list = menuTDao.findAll(query,MenuT.class);
        if (list.size()>0){
            for (MenuT menuT : list){
                removeMenu(menuT.getId());
                removeChildren(menuT.getId());
            }
        }
    }

    /**
     * 修改菜单
     * @param menuT
     */
    @Override
    public void updateMenu(MenuT menuT) {
        //通过id查询菜单
        MenuT menu = findById(menuT.getId());
        //重新赋值
        //验证菜单名称是否重复
        verifyName(menuT);
        menu.setMenuName(menuT.getMenuName());
        menu.setImage(menuT.getImage());
        menu.setUrl(menuT.getUrl());
        menu.setUpdateTime(DateTool.getSystemTime());
        //保存或修改
        menuTDao.saveOrupdate(menu);
    }

    /**
     * 启用/禁用菜单
     * @param id
     * @param flag
     */
    @Override
    public void disableOrEnable(String id, boolean flag) {
        //通过id查询菜单
        MenuT menuT = findById(id);
        //修改状态
        menuTDao.disableOrEnable(menuT,flag);
    }

    /**
     * 验证菜单名称是否重复
     * @param menuT
     */
    @Override
    public void verifyName(MenuT menuT) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").ne(menuT.getId()).
                and("programaId").is(menuT.getProgramaId()).
                and("menuName").is(menuT.getMenuName()).and("removed").is(false));
        MenuT menu = menuTDao.findOne(query,MenuT.class);
        if (menu != null) {
            throw new WhyException(ResultEnum.REPEAT);
        }
    }

    /**
     * 通过id查询菜单
     * @param id
     * @return
     */
    @Override
    public MenuT findById(String id) {
        //通过id查询未删除的菜单
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id).and("removed").is(false));
        MenuT menuT = menuTDao.findOne(query,MenuT.class);
        if (menuT!=null){
            return menuT;
        }else {
            throw new WhyException(ResultEnum.OBJISNULL);
        }
    }

    /**
     * 查询所有菜单
     * @return
     */
    @Override
    public List<MenuT> findAll() {
        //查询未删除和未禁用的所有菜单
        Query query = new Query();
        query.addCriteria(Criteria.where("removed").is(false).and("enable").is(true));
        List<MenuT> list = menuTDao.findAll(query,MenuT.class);
        return list;
    }

    /**
     * 分页查询菜单
     * @param pageDTO
     * @return
     */
    @Override
    public Page findByPage(PageDTO pageDTO) {
        //查询未删除的菜单，并分页传给视图
        Query query = new Query();
        query.addCriteria(Criteria.where("removed").is(false));
        long count = menuTDao.count(query, MenuT.class);
        List<MenuTVo> list = new ArrayList<>();
        for (MenuT menuT : menuTDao.findByPage(query, pageDTO, MenuT.class)) {
            MenuTVo vo = new MenuTVo();
            BeanUtils.copyProperties(menuT, vo);
            vo.setCreateTime(BaseTools.longToString(menuT.getCreateTime()));
            vo.setUpdateTime(BaseTools.longToString(menuT.getUpdateTime()));
            list.add(vo);
        }
        return new Page(pageDTO, count, list);
    }

    /**
     * 通过栏目Id和父级Id查询菜单树状图
     * @param programaId
     * @return
     */
    @Override
    public List<MenuTVo> findMenuTreeByProgramaIdAndPid(String programaId,String pid) {
        Query query = new Query();
        query.addCriteria(Criteria.where("removed").is(false).
                and("enable").is(true).and("programaId").is(programaId).and("pid").is(pid));
        List<MenuT> menuTList = menuTDao.findAll(query,MenuT.class);
        List<MenuTVo> list = new ArrayList<>();
        if (menuTList.size()>0){
            for (MenuT menuT : menuTList){
                MenuTVo vo = new MenuTVo();
                BeanUtils.copyProperties(menuT, vo);
                vo.setLabel(menuT.getMenuName());
                vo.setCreateTime(BaseTools.longToString(menuT.getCreateTime()));
                vo.setUpdateTime(BaseTools.longToString(menuT.getUpdateTime()));
                //获取子菜单
                List<MenuTVo> children = findMenuTreeByProgramaIdAndPid(menuT.getProgramaId(),menuT.getId());
                if (children!=null){
                    vo.setChildren(children);
                }
                list.add(vo);
            }
            return list;
        }else {
            return null;
        }
    }

    /**
     * 查询栏目下的菜单集合
     * @param programaId
     * @return
     */
    @Override
    public List<MenuT> findMenuListByProgramaId(String programaId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("removed").is(false).and("programaId").is(programaId));
        List<MenuT> list = menuTDao.findAll(query,MenuT.class);
        return list;
    }

}
